package p2p.view.components.bases
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.net.FileReference;
	
	import mx.containers.Canvas;
	import mx.containers.VBox;
	import mx.controls.Alert;
	import mx.controls.Button;
	import mx.controls.Label;
	import mx.controls.VideoDisplay;
	import mx.core.FlexGlobals;
	import mx.effects.IEffect;
	import mx.effects.Move;
	import mx.effects.Parallel;
	import mx.events.CloseEvent;
	
	import p2p.controller.events.FileSharingEvent;
	import p2p.data.CallerData;
	import p2p.model.vo.DescriptorVO;
	import p2p.model.vo.P2PSharedVO;
	import p2p.utils.MessageUtils;
	import p2p.view.components.ChatBox;
	import p2p.view.components.ClientsVideoList;
	import p2p.view.components.FileSharingMonitorBase;
	import p2p.view.components.FilesSharingMonitor;
	import p2p.view.components.VideoPlayer;
	
	public class MainBoxBase extends Canvas
	{
		public static const TILE_ITEM_WIDTH:int = 160;
		public static const TILE_ITEM_HEIGHT:int = 120;
		
		public static const VIDEO_PLAYER_WIDTH:Number = 320;
		public static const VIDEO_PLAYER_HEIGHT:Number = 240;
		
		[Bindable]
		public var callerData:CallerData;
		
		[Bindable]
		public var clientsList:ClientsVideoList;
		
		[Bindable]
		public var moveEffect:Move;
		
		[Bindable]
		public var streamChangeParallel:Parallel;
		
		[Bindable]
		public var mainVBox:VBox;
		
		[Bindable]
		public var videoPlayer:VideoPlayer;
		
		[Bindable]
		public var videoDisplay:VideoDisplay;
		
		[Bindable]
		public var btnBrowse:Button;
		
		[Bindable]
		public var btnStartSharing:Button;
		
		[Bindable]
		public var btnStartReceiving:Button;
		
		[Bindable]
		public var btnSaveFile:Button;
		
		[Bindable]
		public var chatBox:ChatBox;
		
		[Bindable]
		public var yourName:Label;
		
		protected var fr:FileReference;
		
		/**
		 * Constructor
		 */
		public function MainBoxBase()
		{
			super();
			callerData = new CallerData();
			
			addEventListener(FileSharingEvent.BROWSE_FILE_SYSTEM, browseFSHandler);
			
			callerData.addEventListener(FileSharingEvent.FILE_SENT, fileSentHandler);
			callerData.addEventListener(FileSharingEvent.FILE_RECEIVING, fileReceivingHandler);
			callerData.addEventListener(FileSharingEvent.FILE_RECEIVED, fileReceivedHandler);
			
			fileSharingMonitor.addEventListener(FileSharingEvent.SAVE_FILE, saveFileHandler);
			fileSharingMonitor.addEventListener(FileSharingEvent.FILE_SAVED, fileSavedHandler);
			fileSharingMonitor.addEventListener(FileSharingEvent.FAULT, faultFileHandler);
			
		}
		
		public function connect(userName:String, userGroup:Object) : void
		{
			callerData.caller.selfName = userName;
			callerData.caller.selfGroupId = userGroup.id;
			callerData.caller.selfGroupName = userGroup.label;
			yourName.text = "You (" + userName + ")";
			callerData.connect();
			videoDisplay.attachCamera(callerData.camera);
		}
		
		protected function onVideoPlayerStreamChange(event:Event) : void
		{
			event.stopPropagation();
			stopEffects();
			var point:Point = clientsList.getSelectedRendererCoordinate();
			if (point)
			{
				point = this.globalToLocal(point);
				moveEffect.xFrom = point.x;
				moveEffect.yFrom = point.y;
				moveEffect.xTo = getVideoPlayerX(mainVBox.x);
				moveEffect.yTo = getVideoPlayerY(mainVBox.y);
				streamChangeParallel.play();
			}
			
		}
		
		protected function getVideoPlayerX(mainBoxX:Number) : Number
		{
			return mainBoxX + 17;
		}
		
		protected function getVideoPlayerY(mainBoxY:Number) : Number
		{
			var globalPoint:Point = chatBox.localToGlobal(new Point(0,0));
			return globalToLocal(globalPoint).y + 1;
		}
		
		private function stopEffects() : void
		{
			for each(var effect:IEffect in streamChangeParallel.children)
			{
				if (effect.isPlaying)
				{
					effect.stop();
				}
			}
			videoPlayer.x = getVideoPlayerX(mainVBox.x);
			videoPlayer.y = getVideoPlayerY(mainVBox.y);
			videoPlayer.width = VIDEO_PLAYER_WIDTH;
			videoPlayer.height = VIDEO_PLAYER_HEIGHT;
		}
		
		
		private function fileReceivedHandler(event:FileSharingEvent) : void
		{
			event.stopPropagation();
			fileSharingMonitor.update(event.fileDescriptor);
		}
		
		private function fileReceivingHandler(event:FileSharingEvent) : void
		{
			event.stopPropagation();
			fileSharingMonitor.update(event.fileDescriptor);
		}
		
		
		private function saveFileHandler(event:FileSharingEvent) : void
		{
			event.stopPropagation();
			var p2pSO:P2PSharedVO = callerData.caller.getReceivedSOByChunkIndex(event.fileDescriptor.startChunkIndex);
			event.fr.save(p2pSO.data, event.fileDescriptor.filename);
		}
		
		private function fileSavedHandler(event:FileSharingEvent) : void
		{
			event.stopPropagation();
			fileSharingMonitor.remove(event.fileDescriptor);
		}
		
		private function faultFileHandler(event:FileSharingEvent) : void
		{
			event.stopPropagation();
			fileSharingMonitor.remove(event.fileDescriptor);
		}
		
		private function browseFSHandler(event:FileSharingEvent) : void
		{
			event.stopPropagation();
			callerData.browseFileSystem();
		}
		
		private function fileSentHandler(event:FileSharingEvent) : void
		{
			event.stopPropagation();
			var fileDescriptor:DescriptorVO = event.fileDescriptor;
			
			var msg:String = MessageUtils.getConfirmationDialogMessage(fileDescriptor.senderName, fileDescriptor.filename, fileDescriptor.size);
		
			showConirmationDialog(msg, "File sharing", yesHandler);
			
			function yesHandler() : void
			{
				FilesSharingMonitor.getInstance().add(event.fileDescriptor);
				callerData.startReceiving(fileDescriptor);
			}
		}
		
		private function showConirmationDialog(msg:String, title:String, yesHandler:Function) : void
		{
			Alert.show(msg, title, Alert.YES | Alert.NO, FlexGlobals.topLevelApplication as Sprite, closeHandler);
			
			function closeHandler(event:CloseEvent) : void
			{
				if (event.detail == Alert.YES)
				{
					yesHandler.call();
				}
			}
		}
		
		private function get fileSharingMonitor() : FileSharingMonitorBase
		{
			return FilesSharingMonitor.getInstance();
		}
		
	}
}